home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_300
/
331_01
/
search.c
< prev
next >
Wrap
Text File
|
1990-06-12
|
15KB
|
535 lines
/*
HEADER: CUG999.04;
TITLE: GED (nee QED) screen editor -- part 4;
DATE: 10/08/86;
DESCRIPTION: "Find, alter, and repeat commands for the GED editor.";
KEYWORDS: find, alter, repeat, pattern matching, search, replace;
FILENAME: GED4.C;
AUTHORS: G. Nigel Gilbert, James W. Haefner, Mel Tearle, G. Osborn;
COMPILERS: DeSmet C;
*/
/*
e/qed/ged screen editor
(C) G. Nigel Gilbert, MICROLOGY, 1981
August-December 1981
Modified: Aug-Dec 1984: BDS-C 'e'(vers 4.6a) to 'qe' (J.W. Haefner)
March 1985: BDS-C 'qe' to DeSmet-C 'qed' (J.W. Haefner)
May 1986: converted to ged - Mel Tearle
FILE: ged4.c
FUNCTIONS: info, findorrep, dofindrep, find
PURPOSE: perform find, alter and repeat commands
*/
#include <stdio.h>
#include "ged.h"
/* ^Q quick key services */
char spatt[81];
char changeto[81];
info()
{
unsigned char c;
puttext();
putmess("|F|ind, |A|lter, |K|ontext/files, |P|aragraph");
while ( (c = getlow()) != 'a' && c != 'f' && c != 'k' &&
c != 'p' && c != ESCKEY );
if (c == ESCKEY)
return;
switch (c) {
case 'f':
findorrep(0);
break;
case 'a':
findorrep(1);
break;
/* the wordstar ^QY clear to end of line command. disabled here because
* this version uses ^Y to delete from cursor to end of line
*
* case 'y':
* cleareol(cursorx,cursory);
* altered = YES;
* text[charn] = '\0';
* break;
*/
case 'k':
envir();
break;
case 'p':
putmess("(F1 = dot help) Delete dot commands while reforming? (Y/N)");
while ( (c = getlow()) != 'y' && c != 'n' && c != ESCKEY && c != F1KEY);
if (c == ESCKEY)
return;
if (c == F1KEY) {
helpdot();
return;
}
if (c == 'y')
roff(0);
else
roff(1);
break;
}
}
/* initiate string search or search and replace. Called by F2 key
* with mode = 0 or from above.
* F2 str F3 search back
* F2 str F4 search fwd
* F2 str1 F2 str2 F3 replace backward
* F2 str1 F2 str2 F4 replace forward
* F3 & F4 & ^L resume
*/
findorrep(mode)
int mode;
{
int i, cnt;
int c;
char tpat[80];
puttext();
putmess("|Find|? ");
c = scans(tpat,80);
if ( c == ESCKEY || !tpat[0] )
return;
strcpy(spatt, tpat); /* move valid string to permanent storage */
if (c == F2KEY)
replace = YES;
else
replace = mode;
if ( replace ) {
putmess("Alter to? ");
c = scans(changeto,80); /* null replacemente allowed */
if (!ctrl) {
if (c == ESCKEY)
return; /* no escape if <esc> can be embedded */
for (i = 0; (changeto[i]); i++) {
if (changeto[i] < ' ') {
error("Use -C option to embed ctrl codes (F7)");
return;
}
}
}
}
else {
changeto[0] = '\0';
}
/* Global is the only option because this would be an awkward way to
* replace one word.
* To do the entire document it is necessary to use the <home> key first
* to jump to line 1.
* It is planned to add a wrap at end of file option, probably as the default.
*/
/*defaults */
nocheck = NO;
cnt = 0;
findir = 1;
if ( c == F3KEY) {
findir = -1;
}
else if (c == F4KEY) {
findir = 1;
}
/* string terminated by <ret> */
else {
if ( replace )
putmess("|B|ackward, |W|ithout asking, |count| ");
else
putmess("|<ret>|, |B|ackwards, |count| ");
if ( scans(opts,5) == ESCKEY )
return;
for ( i = 0; ( c = opts[i]); i++ ) {
switch(tolower(c)) {
case 'b':
findir = -1;
break;
case 'w':
nocheck = YES;
break;
default:
if ( c >= '0' && c <= '9' )
cnt = cnt*10+c-'0';
}
}
}
if ( cnt == 0 ) {
if (replace)
cnt = -1; /* unlimited */
else
cnt = 1;
}
dofindrep(cnt,findir);
}
/* Resume a search or search and replace
* Called by F4, F5, ^L, and from above.
* All searchs and search/replace operations wrap at beginning and end of file.
* The first possible match is the first char beyond
* the cursor position. The last possible match is at the initial
* cursor position.
*/
int ncline, count, oldlen, newlen;
dofindrep(count1,dir)
int count1,dir;
{
int i, j, l2, s0, ocharn, ocline, ncharn;
char c;
char buf[81+35];
puttext();
count = count1;
findir = dir; /* F2 and F3 keys permanently change directin */
oldlen = strlen(spatt);
ocline = cline;
ncline = cline;
ocharn = charn;
ncharn = charn;
if (findir > 0) {
newlen = 1; /* don't start at the cursor */
putmess1(" ", 28, 5);
while (i = find(charn+newlen, cline, LLIM, lastl)) {
if (i < 0)
return;
if (!dorep())
return;
ncline = cline;
ncharn = charn;
}
putmess1("EOF", 28, 5);
wait(1);
puttext();
charn = newlen = 0;
cline = 1;
plast = -1;
gettext(cline, 0);
while (i = find(charn+newlen, cline, ocharn, ocline)) {
if (i < 0)
return;
s0 = strlen(text);
if (!dorep())
return;
if (cline == ocline)
ocharn += strlen(text) - s0;
ncline = cline;
ncharn = charn;
}
}
else {
s0 = strlen(text);
while (i = find(charn-1, cline, 0, cline)) {
if (i < 0)
return;
if (!dorep())
return;
ncline = cline;
ncharn = charn;
}
ocharn += strlen(text) - s0; /* terminal point changes with replacemets */
charn = 0;
putmess1(" ", 28, 5);
while (i = find(charn-1, cline, 0, 1)) {
if (i < 0)
return;
if (!dorep())
return;
ncline = cline;
ncharn = charn;
}
puttext();
putmess1("BOF", 28, 5);
wait(1);
cline = lastl;
plast = -1;
gettext(cline, 0);
charn=strlen(text);
while (i = find(charn-1, cline, ocharn, ocline)) {
if (i < 0) {
return;
}
if (!dorep())
return;
ncline = cline;
ncharn = charn;
}
}
strcpy(buf,"Search for '");
strcat(buf,spatt);
strcat(buf,"' fails");
error1(buf);
wait(2);
putstatusline(ncline);
charn = ncharn;
moveline(ncline-cline);
curson(YES);
return;
}
int dorep()
{
int i, j;
char c;
if (!replace)
return 0;
if ( nocheck )
c = 'y';
else {
blankedmess = YES;
putlineno(cline);
putmess1("Replace |<esc>|/|Y|/|N| ?", 34, 37);
do {
gotoxy(55,0); /* position just after prompt */
for (i=0; i < 3000; i++);
resetpcursor();
for (i=0; i < 3000; i++);
}
while (chkbuf() == 0);
c = testlow();
}
switch(c) {
case 'y' :
newlen = strlen(changeto); /* null replacement allowed */
if ( strlen(text) + newlen - oldlen + 1 > LLIM ) {
error(" Line would be too long ");
return;
}
/* delete the old word */
for ( j = charn; (text[j] = text[j + oldl